home *** CD-ROM | disk | FTP | other *** search
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; Flat-Model Programming Using FLAT.INC
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ; This program illustrates usage of FLAT.INC to perform flat-model
- ;protected-mode programming in DOS. The program performs a simple hex
- ;dump of memory from any requested address. At the input prompt, type
- ;the starting hex address to be viewed and hit ENTER. Alternatively,
- ;hit DOWN/UP ARROW or PAGE UP/DOWN to scroll. Hit ESC to exit.
- ; WARNING: This program may crash with a page fault (exception 14)
- ;if page protection is being enforced by a memory manager or operating
- ;system. Run the program under a clean configuration or HIMEM.SYS to
- ;get an unrestricted view of memory.
- ; The key to this program is the include file FLAT.INC. FLAT.INC is
- ;highly documented. It is suggested that it be thoroughly read. This
- ;program also makes considerable use of PMIO.INC for input/output. This
- ;file also has extensive documentation.
- ; The following template reveals the simplicity of flat-model programs
- ;using FLAT.INC:
- ;
- ; INCLUDE FLAT.INC ;Always first line in program
- ;
- ;MAIN PROC NEAR ;Execution always begins at MAIN
- ; .
- ; .
- ; RET ;Execution ends here
- ;MAIN ENDP
- ;
- ; [Other Procedures] ;All procedures must be near
- ;
- ; [Program Data]
- ;
- ; END
- ;
- ; The order of MAIN, other procedures, and data is not important. The
- ;important things are that FLAT.INC be the first statement, that execution
- ;begin at MAIN, and that MAIN and all other procedures be near.
- ; FLAT.INC enables a close approximation of the flat model. In the true
- ;flat model all segments have base address at zero and limits equal to
- ;4Gb. The flat model is therefore unsegmented. One of the principle
- ;attractions of the model is that segment registers never have to be
- ;reloaded. The XLIB flat model is like the true flat model in all regards
- ;except that segments are not based at zero. Unfortunately, limitations
- ;to DOS disallow elimination of this difference. However, the difference
- ;has surprisingly little affect upon code. In fact, the difference
- ;becomes relevant only when the program must access external data. The
- ;addresses to such data must be normalized by subtracting the segment
- ;base address from their offsets. For example, the color screen would
- ;be accessed in the flat model at offset B8000H. In the approximate
- ;model, the offset must be B8000H - BASEADDRESS, where BASEADDRESS is
- ;the linear address of the segment base. This methodology is used in
- ;the program below.
- ; NOTICE: TASM programmers should remove the semicolon on the line
- ;defining TASMMODE.
-
- TRUE EQU 1
- FALSE EQU 0
-
- ;TASMMODE EQU TRUE ;Remove comment for TASM
- INCLUDE FLAT.INC
-
- ;ASCII codes and scan codes
- CR EQU 13
- UP EQU 48H
- DOWN EQU 50H
- PAGEDOWN EQU 51H
- PAGEUP EQU 49H
-
- ; Upon entry to MAIN, DS:EBX will point to the program segment prefix, and
- ;EDX will equal the linear base address of CS, DS, and SS. ES will be a
- ;true flat-model segment (base = 0). All of these segments will have 4Gb
- ;limits. FS will contain a selector to segment DSEG which is the XLIB data
- ;segment. See XLIB documentaion for information about public symbols in
- ;DSEG. GS will contain a selector to DGROUP. Both FS and GS will have 64K
- ;limits.
- ; FLAT.INC can be configured to change the segment settings above. See
- ;comments in FLAT.INC for details.
-
- ;Perform hex dump from anywhere in memory. Start at address 00000000H and
- ;let user key in addresses thereafter.
- MAIN PROC NEAR
- XOR ESI,ESI ;ESI will be the linear address of displayed memory
- MOV EDI,ESI
- SUB EDI,EDX ;EDI will be the normalized address of displayed memory
- MAINLOOP: PUSH ESI ;Save addresses
- PUSH EDI
- CALL CLS ;Clear screen
- MOV ECX,368 ;Print 368 bytes, 16 per line, 23 lines
- LINELOOP: MOV EAX,ESI ;Print linear address of hex dump for each line
- CALL PHD ;PHD = "Print Hexadecimal DWORD" in EAX
- MOV AL,":"
- CALL PCH ;PCH = "Print Character" in AL
- MOV AL,4
- CALL SPC ;SPC prints AL spaces
- BYTELOOP: MOV AL,[EDI] ;Get and display memory
- CALL PHB ;PHB = "Print Hexadecimal Byte" in AL
- MOV AL,2 ;Print 2 spaces
- CALL SPC
- INC ESI ;Advance to next byte
- INC EDI
- DEC ECX ;Decrement byte counter
- TEST ECX,0FH ;See if complete line (16 bytes) yet printed
- JNZ BYTELOOP
- CALL CRLF ;Do carriage return and linefeed to next line
- OR ECX,ECX ;See if all 23 lines printed
- JNZ LINELOOP
- POP EDI ;POP normalized address
- POP ESI ;POP linear address
- MOV EBX,OFFSET PROMPT ;Display input prompt at bottom line
- CALL PSTR ;PSTR = "Print String" at DS:EBX
- MOV HEXADDRESS,0 ;Make initial string null
- MOV EBX,OFFSET HEXADDRESS
- MOV EAX,8 ;Limit input field to 8 characters
- CALL EDITSTR ;Input new address. Returned AX defines last typed character. See EDITSCRN in PMIO.INC
- OR AH,AH ;See if a nonASCII key was pressed last
- JS CHECKDOWN
- CMP AL,CR ;See if CR was last character typed
- JNE EXIT
- CALL CONVERTHEX ;Convert hex string at DS:EBX to numeric in EAX
- AND AL,0F0H ;Set requested address to mod 16 boundary
- MOV ESI,EAX ;Update linear address in ESI
- MOV EDI,EAX ;Compute new normalized address in EDI
- SUB EDI,EDX
- JMP MAINLOOP
- CHECKDOWN: CMP AL,DOWN ;See if DOWN ARROW was pressed
- JNE CHECKUP
- ADD EDI,16 ;Move screen down one line (16 bytes)
- ADD ESI,16
- JMP MAINLOOP
- CHECKUP: CMP AL,UP ;See if UP ARROW was pressed
- JNE CHECKPAGEDOWN
- SUB EDI,16 ;Move screen up one line
- SUB ESI,16
- JAE MAINLOOP
- MEMBOTTOM: XOR ESI,ESI ;Are at bottom of memory
- XOR EDI,EDI
- SUB EDI,EDX
- JMP MAINLOOP
- CHECKPAGEDOWN: CMP AL,PAGEDOWN ;See if PAGE DOWN was pressed
- JNE CHECKPAGEUP
- ADD ESI,368 ;Move down one page
- ADD EDI,368
- JMP MAINLOOP
- CHECKPAGEUP: CMP AL,PAGEUP ;See if PAGE UP was pressed
- JNE EXIT
- SUB EDI,368 ;Move up one page
- SUB ESI,368
- JAE MAINLOOP
- JMP MEMBOTTOM
- EXIT: RET
- MAIN ENDP
-
- PROMPT DB "Input Hex Address: ",0 ;Input prompt
- HEXADDRESS DB 9 DUP(0) ;String for 8 hex digits plus zero termination character
-
- ;Convert hex string at DS:EBX to numeric in EAX. Does not check syntax.
- CONVERTHEX PROC NEAR
- PUSH EBX
- PUSH EDX
- XOR EAX,EAX ;Accumulate value in EAX
- XOR EDX,EDX
- CHARLOOP: MOV DL,[EBX] ;Get ASCII hex digit
- SUB DL,48 ;Convert to ASCII digit to numeric
- JB EXIT ;String is terminated with 0
- SHL EAX,4 ;Multiply cumulative by 16
- ADD EAX,EDX ;Accumulate last digit
- INC EBX ;Advance to next digit
- JMP CHARLOOP
- EXIT: POP EDX
- POP EBX
- RET
- CONVERTHEX ENDP
-
- INCLUDE PMIO.INC ;Protected-mode input/output
-
- END
-